﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using PSE.ProcessManager.Entity;
using System.Management;

namespace PSE.ProcessManager.Server.InteligenceManager
{
    /*
    public class InstanceProcess : IDisposable
    {
        private System.Diagnostics.Process _process;
        private ManualResetEvent _processStarted = new ManualResetEvent(false);
        private bool _hasError = false;

        public InstanceProcess(string productKey, InstanceEntity instance)
        {
            _productKey = productKey;
            _instance = instance;
        }

        public int Pid
        {
            get
            {
                if (this.IsStarted)
                    return _process.Id;
                else
                    return -1;
            }
        }

        /// <summary>
        /// Indica se o processo foi iniciado
        /// </summary>
        public bool IsStarted
        {
            get
            {
                bool started = false;

                if (_process != null)
                {
                    _process.Refresh();
                    started = !_process.HasExited;
                }

                return started;
            }
        }

        private string _productKey = null;
        public string ProductKey
        {
            get { return _productKey; }
        }

        private InstanceEntity _instance = null;
        public InstanceEntity Instance
        {
            get { return _instance; }
        }

        #region Tratamento de eventos
        private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            // Ao receber dados do processo filho libera o método Start para continuar
            _processStarted.Set();
        }

        private void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
        {
            _hasError = true;

            // Ao receber um erro do processo filho libera o método Start para continuar
            _processStarted.Set();
        }
        #endregion

        #region StartProcess
        /// <summary>
        /// Inicia o processo
        /// </summary>
        /// <returns>True se iniciou o processo com sucesso, False se ocorreu algum erro</returns>
        public void StartProcess()
        {
            if (this.IsStarted)
                throw new InvalidOperationException("Cannot start process, it is already started");

            this.Dispose();

            try
            {
                //recuperar o caminho do exe do inteligence manager instance
                string inteligenceManagerInstanceExePath = Assembly.GetAssembly(typeof(InteligenceManagerInstance.InteligenceManager)).Location;
                int inteligenceManagerPID = System.Diagnostics.Process.GetCurrentProcess().Id;

                _process = new System.Diagnostics.Process();

                _process.StartInfo.Arguments = inteligenceManagerPID.ToString() + " " + '"' + _productKey + '"' + " " + '"' + _instance.Name + '"';

                _process.StartInfo.RedirectStandardInput = true;
                _process.StartInfo.RedirectStandardOutput = true;
                _process.StartInfo.RedirectStandardError = true;

                _process.StartInfo.FileName = inteligenceManagerInstanceExePath;
                _process.StartInfo.CreateNoWindow = true;
                _process.StartInfo.UseShellExecute = false;

                _process.OutputDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);
                _process.ErrorDataReceived += new DataReceivedEventHandler(Process_ErrorDataReceived);

                _process.Start();

                _process.BeginErrorReadLine();
                _process.BeginOutputReadLine();

                // Espera o inicio do processo
                _processStarted.WaitOne();

                if (_hasError)
                {
                    throw new InvalidOperationException("Cannot start process, see log for details");
                }
            }
            catch
            {
                this.Dispose();
                throw;
            }

            return;
        }
        #endregion

        #region VerifyIsStarted
        private void VerifyIsStarted()
        {
            if (!this.IsStarted)
                throw new InvalidOperationException("Cannot execute this operation, the process has not been started");
        }
        #endregion

        #region CloseProcess
        /// <summary>
        /// Fecha o processo
        /// </summary>
        public void CloseProcess()
        {
            if (!this.IsStarted)
                throw new InvalidOperationException("Cannot close process, it has not been started");

            this.Dispose();
        }
        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            _hasError = false;
            _processStarted.Reset();

            // Finalizando processo
            if (_process != null)
            {
                if (this.IsStarted)
                {
                    string wmiQuery = string.Format("SELECT ProcessId FROM Win32_Process WHERE Name='PSE.ProcessManager.Server.Process.Executor.exe' AND ParentProcessId={0}", _process.Id); 
                    ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmiQuery); 
                    ManagementObjectCollection retObjectCollection = searcher.Get(); 
                    foreach (ManagementObject retObject in retObjectCollection) 
                    {
                        System.Diagnostics.Process.GetProcessById(Convert.ToInt32(retObject["ProcessId"])).Kill(); 
                    }

                    _process.Kill();
                }

                _process.OutputDataReceived -= new DataReceivedEventHandler(Process_OutputDataReceived);
                _process.ErrorDataReceived -= new DataReceivedEventHandler(Process_ErrorDataReceived);
                _process.Dispose();
                _process = null;
            }
        }

        #endregion
    }
   */
}
